use crate::lexer_mod::token_type_enum::{Compared, Operator};
#[derive(Debug)]
pub struct Expression {
    pub line: i32,
    pub row: i32,
    pub exp_type: ExpressionType,
}
#[derive(Debug)]
pub enum ExpressionType {
    Statement(Statement),
    ConstString(String),
    Null,
    ConstDeduceNum,
    ConstFloat(f32),
    ConstNum(i32),
    ConstLong(i64),
    ConstLongLong(i128),
    ConstBool(bool),
    ArrayInit {
        exps: Vec<Expression>,
    },
    ///代码块,可以有返回值
    Block {
        body: Vec<Expression>,
    },
    /// 条件 & 执行 & 否则 , 可以有返回值
    If {
        condition: Box<Expression>,
        then: Box<Expression>,
        not: Option<Box<Expression>>,
    },

    For {
        ///初始化
        init: Box<Expression>,
        ///继续条件
        condition: Box<Expression>,
        ///完成循环
        increment: Box<Expression>,
        ///主体
        body: Box<Expression>,
    },

    While {
        ///继续条件
        condition: Box<Expression>,
        ///主体
        body: Box<Expression>,
    },
    ///变量引用
    VariableRead {
        var_name: AccessTarget,
    },
    ///变量写入
    VariableWrite {
        var_name: AccessTarget,
        result: Box<Expression>,
    },
    ///数学表达式
    Math {
        left: Box<Expression>,
        operator: Operator,
        right: Box<Expression>,
    },
    ///比较表达式
    Compared {
        left: Box<Expression>,
        compared: Compared,
        right: Box<Expression>,
    },
    ///一元表达式
    Monomial {
        operator: Operator,
        value: Box<Expression>,
    },
    ///返回值
    Return {
        value: Option<Box<Expression>>,
    },
    Break {
        label: Option<String>,
    },
    Goto {
        label: String,
    },
    Label {
        label_name: String,
    },
    Continue,
}
///声明
#[derive(Debug)]
pub enum Statement {
    Variable {
        ///文档
        document: Option<String>,
        var_type: Type,
        var_name: String,
        var_init: Option<Box<Expression>>,
    },
    ///函数名
    Function {
        ///文档
        document: Option<String>,
        ///函数名
        func_name: Option<String>,
        return_type: Type,
        ///参数定义
        args: Vec<Parameter>,
        ///代码
        body: Box<Expression>,
    },
    Class {
        ///文档
        document: Option<String>,
        class_name: String,
        member: Box<Expression>,
    },
}

#[derive(Debug)]
pub struct Parameter {
    pub var_type: Type,
    pub var_name: String,
}

#[derive(Debug)]
pub enum AccessTarget {
    ///直接对象访问
    Variable(String),
    ///字段访问
    Field {
        to: Box<Expression>,
        from: Box<Expression>,
    },
    ///数组访问
    Index {
        array: Box<AccessTarget>,
        index: Box<Expression>,
    },
    ///函数调用
    Call {
        callee: Option<Box<AccessTarget>>,
        func_name: String,
        args: Vec<Expression>,
    },
}
#[derive(Debug)]
pub enum Type {
    None,
    Int,
    String,
    Float,
    Long,
    LongLong,
    Bool,
    Object(String),
    ArrayType {
        array_type: Box<Type>,
        array_size: Option<i32>,
    },
}
